<template>
  <div class="x-charts" :style="elStyle">
    <div ref="XChartsRef" :style="{ height: `${$props.height}px` }" />
  </div>
</template>

<script lang="ts">
  import * as echarts from 'echarts'
  import {computed, defineComponent, reactive, toRefs, ref, watch, onMounted, toRef, markRaw} from 'vue'

  export default defineComponent({
    name: 'XCharts',
    components: {},
    props: {
      options: {
        type: Object,
        default: () => {}
      },
      height: {
        type: [Number, String],
        default: 400
      },
      background: {
        type: String,
        default: '#fff'
      }
    },
    setup($props) {
      let chartsEl = ref<echarts.ECharts | null>(null)
      const XChartsRef = ref<HTMLElement>()
      const $state: any = reactive({
        ...toRefs($props),
        elStyle: computed(() => {
          return {
            background: $props.background
          }
        }),
        defaultOptions: {
          grid: {
            top: 50,
            left: 30,
            right: 30,
            bottom: 30,
            containLabel: true
          },
          tooltip: {
            trigger: 'axis',
            axisPointer: {
              type: 'cross',
              label: {
                backgroundColor: '#6a7985'
              }
            }
          },
          xAxis: {
            type: 'category',
            boundaryGap: false,
            axisLabel: {
              color: '#999999'
            },
            axisLine: {
              lineStyle: {
                color: '#EEEEEE'
              }
            }
          },
          yAxis: {
            type: 'value',
            axisLabel: {
              color: '#999999'
            },
            axisLine: {
              lineStyle: {
                color: '#999999'
              }
            }
          }
        }
      })

      watch(
        () => $props.options,
        () => {
          setChartsOption()
        },
        {
          deep: true
        }
      )

      const setChartsOption = () => {
        if (chartsEl.value) {
          const options = mergeOptions({}, $state.defaultOptions, $props.options || {})
          // console.log('setChartsOption-> ', JSON.stringify(options))
          chartsEl.value.setOption(options)
        } else {
          console.warn('$state.chartsEl-> ', null)
        }
      }

      const isObject = (obj: any) => {
        return Object.prototype.toString.call(obj) === '[object Object]'
      }

      const isArray = (arr: any) => {
        return Array.isArray(arr)
      }

      const mergeOptions = (target: any, ...arg: any) => {
        return arg.reduce((acc: any, cur: any) => {
          return Object.keys(cur).reduce((subAcc, key) => {
            const srcVal = cur[key]
            if (isObject(srcVal)) {
              subAcc[key] = mergeOptions(subAcc[key] ? subAcc[key] : {}, srcVal)
            } else if (isArray(srcVal)) {
              // series: []，下层数组直接赋值
              subAcc[key] = srcVal.map((item: any, idx: any) => {
                if (isObject(item)) {
                  const curAccVal = subAcc[key] ? subAcc[key] : []
                  return mergeOptions(curAccVal[idx] ? curAccVal[idx] : {}, item)
                } else {
                  return item
                }
              })
            } else {
              subAcc[key] = srcVal
            }
            return subAcc
          }, acc)
        }, target)
      }

      onMounted(() => {
        if (XChartsRef.value) {
          chartsEl.value = markRaw(echarts.init(XChartsRef.value))
          setChartsOption()
          window.onresize = () => {
            chartsEl.value?.resize()
          }
        }
      })

      return {
        ...toRefs($state),
        XChartsRef,
        chartsEl
      }
    }
  })
</script>

<style></style>
